<?php
//
//	file: includes/cash/cash_main.php
//	begin: 30/10/2006
//	$Author: christopher $
//	$Revision: 14 $
//	$Date: 2007-10-08 14:55:03 +0000 (Mon, 08 Oct 2007) $
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//
//	description: loader for cash

if ( !defined('IN_PHPBB') )
{
	die('Hacking attempt');
	exit;
}

if ( !defined('CASH_CURRENT_VERSION') )
{
	// Cash Mod Constants
	define('CASH_CURRENT_VERSION','0.5.0');
	define('PERCHAR_DEC_BONUS',3);
	define('CASH_LOG_ACTION_DELIMETER','@-@');
	define('CASH_EVENT_DELIM1','#');
	define('CASH_EVENT_DELIM2','@');

	// Log Settings - the order here matters. don't change it. only add to the end of the list.
	$i = 0;
	define('CASH_LOG_DONATE', $i++);
	define('CASH_LOG_ADMIN_MODEDIT', $i++);
	define('CASH_LOG_ADMIN_CREATE_CURRENCY', $i++);
	define('CASH_LOG_ADMIN_DELETE_CURRENCY', $i++);
	define('CASH_LOG_ADMIN_RENAME_CURRENCY', $i++);
	define('CASH_LOG_ADMIN_COPY_CURRENCY',$i++);

	// Allowance Time
	define('CASH_ALLOW_DAY', 1);
	define('CASH_ALLOW_WEEK', 2);
	define('CASH_ALLOW_MONTH', 3);
	define('CASH_ALLOW_YEAR', 4);

	// Cash groups
	define('CASH_GROUPS_LEVEL', 1);
	define('CASH_GROUPS_RANK', 2);
	define('CASH_GROUPS_USERGROUP', 3);

	// Cash groups status
	define('CASH_GROUPS_DEFAULT', 1);
	define('CASH_GROUPS_CUSTOM', 2);
	define('CASH_GROUPS_OFF', 3);

	// Bitmask filters - the order here matters. don't change it. only add to the end of the list.
	$i = 0;
	define('CURRENCY_ENABLED', 1 << $i++);
	define('CURRENCY_IMAGE', 1 << $i++);
	define('CURRENCY_PREFIX', 1 << $i++);
	define('CURRENCY_INCLUDEQUOTES', 1 << $i++);
	define('CURRENCY_VIEWPROFILE', 1 << $i++);
	define('CURRENCY_VIEWTOPIC', 1 << $i++);
	define('CURRENCY_VIEWMEMBERLIST', 1 << $i++);
	define('CURRENCY_DONATE', 1 << $i++);
	define('CURRENCY_MODEDIT', 1 << $i++);
	define('CURRENCY_ALLOWNEG', 1 << $i++);
	define('CURRENCY_FORUMLISTTYPE', 1 << $i++);
	define('CURRENCY_EXCHANGEABLE', 1 << $i++);

	// Cash tables
	define('CASH_TABLE', $table_prefix.'cash');
	define('CASH_EVENTS_TABLE', $table_prefix.'cash_events');
	define('CASH_EXCHANGE_TABLE', $table_prefix.'cash_exchange');
	define('CASH_GROUPS_TABLE', $table_prefix.'cash_groups');
	define('CASH_LOGS_TABLE', $table_prefix.'cash_log');
}

// do not go further during login or installation
if ( defined('IN_LOGIN') || defined('IN_INSTALL') )
{
	return;
}

// intall directory still present
if ( file_exists(phpbb_realpath($config->root . 'install_cash')) )
{
	if ( $config->data['mod_cash'] != CASH_CURRENT_VERSION )
	{
		header('Location: ' . $config->url('install_cash/install'));
		exit;
	}
	else
	{
		message_die(GENERAL_MESSAGE, 'Please remove install_cash/ directory');
	}
}

if ( !$config->data['mod_cash'] )
{
	return;
}

class cash_version
{
	function read(&$data)
	{
		$data[] = array('app_name' => 'Cash', 'app_desc' => '', 'app_marker' => 'mod_cash', 'app_author' => 'impleri', 'app_author_url' => 'http://impleri.net/', 'app_server' => 'mods.impleri.net', 'app_file' => '/download/versions.dta', 'app_protocol' => 'native', 'app_page' => 'http://mods.impleri.net/download.php');
	}
}

//quickswap
function qs(&$int1, &$int2)
{
	$int3 = $int2;
	$int2 = $int1;
	$int1 = $int3;
}

// yay for the euclidean algorithm!
function gcd($int1, $int2)
{
	$int1 = (intval($int1) >= 0)?intval($int1):intval($int1 * -1);
	$int2 = (intval($int2) >= 0)?intval($int2):intval($int2 * -1);
	if ( $int1 < $int2 )
	{
		qs($int1,$int2);
	}
	while ( $int1 > $int2)
	{
		$factor = intval($int1/$int2);
		$int1 -= ($factor * $int2);
		if ( $int1 > 0 )
		{
			qs($int1, $int2);
		}
	}
	return $int2;
}

function quoteslash($text,$quotes)
{
	if ( is_array($quotes) )
	{
		for ($i = 0; $i < count($quotes); $i++ )
		{
			if ( $quotes[$i] == '\'' )
			{
				$text = str_replace('\'','&#039;',$text);
			}
			else if ( $quotes[$i] == '"' )
			{
				$text = str_replace('"','&quot;',$text);
			}
			else if ( $quotes[$i] != '' )
			{
				$text = str_replace($quotes[$i],'\\' . $quotes[$i],$text);
			}
		}

	}
	else
	{
		if ( $quotes == '\'' )
		{
			$text = str_replace('\'','&#039;',$text);
		}
		else if ( $quotes == '"' )
		{
			$text = str_replace('"','&quot;',$text);
		}
		else if ( $quotes != '' )
		{
			$text = str_replace($quotes,'\\' . $quotes,$text);
		}
	}
	return $text;
}

function cash_create_log($type,$action,$message = '')
{
	global $db;
	$action = implode(CASH_LOG_ACTION_DELIMETER,$action);
	$current_time = time();
	$sql = "INSERT INTO " . CASH_LOGS_TABLE . "
			(log_time,log_type,log_action,log_text)
			VALUES(" . $current_time . ", " . $type . ", '" . str_replace("'","''",$action) . "', '" . $message . "')";
	$db->sql_query($sql, false, __LINE__, __FILE__, false);
}

function cash_event_unpack($string)
{
	$cash_amounts = array();
	if ( strlen($string) )
	{
		$cash_entries = explode(CASH_EVENT_DELIM1,$string);
		for ( $i = 0; $i < count($cash_entries); $i++ )
		{
			if ( strlen($cash_entries[$i]) )
			{
				$temp = explode(CASH_EVENT_DELIM2,$cash_entries[$i]);
				if ( isset($temp[0]) && isset($temp[1]) )
				{
					$cash_amounts[intval($temp[0])] = _type_cast($temp[1], TYPE_FLOAT);
				}
			}
		}
	}
	return $cash_amounts;
}

function cash_quotematch(&$message,$bbcode_uid)
{
	$length = strlen($message);
	$starttag = '[quote:' . $bbcode_uid;
	$startarray = array();
	$endtag = '[/quote:' . $bbcode_uid . ']';
	$endarray = array();
	$locater = 0;
	$current_position = strpos($message,$starttag,$locater);
	while ( $current_position !== false )
	{
		$startarray[] = $current_position;
		$locater = $current_position + strlen($starttag);
		$current_position = strpos($message,$starttag,$locater);
	}
	$startarray[] = $length + 10;
	$locater = 0;
	$current_position = strpos($message,$endtag,$locater);
	while ( $current_position !== false )
	{
		$endarray[] = $current_position + strlen($endtag);
		$locater = $current_position + strlen($endtag);
		$current_position = strpos($message,$endtag,$locater);
	}
	$endarray[] = $length + 10;
	if ( count($startarray) > 1 )
	{
		$start = 0;
		$end = 0;
		$stack = 0;
		$startpos = 0;
		$endpos = 0;
		for ( $i = 0; $i < (count($startarray) + count($endarray) - 2); $i++ )
		{
			if ( $stack == 0 )
			{
				$startpos = $startarray[$start];
				$start++;
				$stack++;
			}
			else
			{
				if ( $startarray[$start] < $endarray[$end] )
				{
					$start++;
					$stack++;
				}
				else
				{
					$endpos = $endarray[$end];
					$end++;
					$stack--;
				}
				if ( $stack == 0 )
				{
					$difference = $endpos - $startpos;
					$length -= $difference;
				}
			}
		}
	}
	return $length;
}

function cash_clause( $clause, $action )
{
	$action = explode(CASH_LOG_ACTION_DELIMETER,$action);
	$text = call_user_func_array('sprintf',array_merge(array($clause),$action));
	$text = str_replace('&quot;','"',$text);
	return $text;
}

// This is if you do not have Advanced Messages installed
if ( !$config->data['mod_advanced_messages'] )
{
	function cash_pm(&$targetdata,$privmsg_subject,&$message)
	{
		global $db, $board_config, $lang, $userdata, $phpbb_root_path, $phpEx, $html_entities_match, $html_entities_replace;
		global $user;
		//
		// It looks like we're sending a PM!
		// NOTE: most of the following code is shamelessly "reproduced" from privmsg.php
		//

		include($phpbb_root_path . 'includes/bbcode.'.$phpEx);
		include($phpbb_root_path . 'includes/functions_post.'.$phpEx);

		//
		// Toggles
		//
		if ( !$board_config['allow_html'] )
		{
			$html_on = 0;
		}
		else
		{
			$html_on = $userdata['user_allowhtml'];
		}

		$bbcode_on = TRUE;

		if ( !$board_config['allow_smilies'] )
		{
			$smilies_on = 0;
		}
		else
		{
			$smilies_on = $userdata['user_allowsmile'];
		}

		$attach_sig = $userdata['user_attachsig'];

		//
		// Flood control
		//
		$sql = "SELECT MAX(privmsgs_date) AS last_post_time
			FROM " . PRIVMSGS_TABLE . "
			WHERE privmsgs_from_userid = " . $userdata['user_id'];
		$result = $db->sql_query($sql, false, __LINE__, __FILE__, true);
		$db_row = $db->sql_fetchrow($result);

		$last_post_time = $db_row['last_post_time'];
		$current_time = time();

		if ( ( $current_time - $last_post_time ) < $config->data['flood_interval'])
		{
			message_die(GENERAL_MESSAGE, $user->lang('Flood_Error'));
		}
		//
		// End Flood control
		//

		$msg_time = time();
		$bbcode_uid = make_bbcode_uid();

		$privmsg_message = prepare_message($message, $html_on, $bbcode_on, $smilies_on, $bbcode_uid);

		//
		// See if recipient is at their inbox limit
		//
		$sql = "SELECT COUNT(privmsgs_id) AS inbox_items, MIN(privmsgs_date) AS oldest_post_time
			FROM " . PRIVMSGS_TABLE . "
			WHERE ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
					OR privmsgs_type = " . PRIVMSGS_READ_MAIL . "
					OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . " )
				AND privmsgs_to_userid = " . $targetdata['user_id'];
		$result = $db->sql_query($sql, false, __LINE__, __FILE__, false);
		$sql_priority = ( SQL_LAYER == 'mysql' ) ? 'LOW_PRIORITY' : '';

		if ( $inbox_info = $db->sql_fetchrow($result) )
		{
			if ( $inbox_info['inbox_items'] >= $board_config['max_inbox_privmsgs'] )
			{
				$sql = "SELECT privmsgs_id FROM " . PRIVMSGS_TABLE . "
					WHERE ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
							OR privmsgs_type = " . PRIVMSGS_READ_MAIL . "
							OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . "  )
						AND privmsgs_date = " . $inbox_info['oldest_post_time'] . "
						AND privmsgs_to_userid = " . $targetdata['user_id'];
				$result = $db->sql_query($sql, false, __LINE__, __FILE__, false);
				$old_privmsgs_id = $db->sql_fetchrow($result);
				$old_privmsgs_id = $old_privmsgs_id['privmsgs_id'];

				$sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
					WHERE privmsgs_id = $old_privmsgs_id";
				$result = $db->sql_query($sql, false, __LINE__, __FILE__, false);
		if ( !$config->data['mod_cash'] )		$sql = "DELETE $sql_priority FROM " . PRIVMSGS_TEXT_TABLE . "
					WHERE privmsgs_text_id = $old_privmsgs_id";
				$result = $db->sql_query($sql, false, __LINE__, __FILE__, false);
			}
		}

		$sql_info = "INSERT INTO " . PRIVMSGS_TABLE . " (privmsgs_type, privmsgs_subject, privmsgs_from_userid, privmsgs_to_userid, privmsgs_date, privmsgs_ip, privmsgs_enable_html, privmsgs_enable_bbcode, privmsgs_enable_smilies, privmsgs_attach_sig)
			VALUES (" . PRIVMSGS_NEW_MAIL . ", '" . str_replace("\'", "''", $privmsg_subject) . "', " . $userdata['user_id'] . ", " . $targetdata['user_id'] . ", $msg_time, '$user_ip', $html_on, $bbcode_on, $smilies_on, $attach_sig)";
		$result = $db->sql_query($sql_info, BEGIN_TRANSACTION, __LINE__, __FILE__, true);
		$privmsg_sent_id = $db->sql_nextid();

		$sql = "INSERT INTO " . PRIVMSGS_TEXT_TABLE . " (privmsgs_text_id, privmsgs_bbcode_uid, privmsgs_text)
			VALUES ($privmsg_sent_id, '" . $bbcode_uid . "', '" . str_replace("\'", "''", $privmsg_message) . "')";
		$result = $db->sql_query($sql, END_TRANSACTION, __LINE__, __FILE__, false);
		//
		// Add to the users new pm counter
		//
		$sql = "UPDATE " . USERS_TABLE . "
			SET user_new_privmsg = user_new_privmsg + 1, user_last_privmsg = " . time() . "
			WHERE user_id = " . $targetdata['user_id'];
		$status = $db->sql_query($sql, false, __LINE__, __FILE__, false);
		if ( $targetdata['user_notify_pm'] && !empty($targetdata['user_email']) && $targetdata['user_active'] )
		{
			$script_name = preg_replace('/^\/?(.*?)\/?$/', "\\1", trim($board_config['script_path']));
			$script_name = ( $script_name != '' ) ? $script_name . '/privmsg.'.$phpEx : 'privmsg.'.$phpEx;
			$server_name = trim($board_config['server_name']);
			$server_protocol = ( $board_config['cookie_secure'] ) ? 'https://' : 'http://';
			$server_port = ( $board_config['server_port'] <> 80 ) ? ':' . trim($board_config['server_port']) . '/' : '/';

			include($phpbb_root_path . 'includes/emailer.'.$phpEx);
			$emailer = new emailer($board_config['smtp_delivery']);

			$emailer->from($board_config['board_email']);
			$emailer->replyto($board_config['board_email']);

			$emailer->use_template('privmsg_notify', $targetdata['user_lang']);
			$emailer->email_address($targetdata['user_email']);
			$emailer->set_subject($lang['Notification_subject']);

			$emailer->assign_vars(array(
				'USERNAME' => $to_username,
				'SITENAME' => $board_config['sitename'],
				'EMAIL_SIG' => (!empty($board_config['board_email_sig'])) ? str_replace('<br />', "\n", "-- \n" . $board_config['board_email_sig']) : '',

				'U_INBOX' => $server_protocol . $server_name . $server_port . $script_name . '?folder=inbox')
			);

			$emailer->send();
			$emailer->reset();
		}
	}
}

// Backwards compatibility for PHP < 4.3
// Honestly, though, if you have PHP less than 4.3, you should look at upgrading to 4.3 or 4.4
// Debian Sarge, which was released in early 2005, even has 4.3.10
$version = explode('.',phpversion());
if (intval($version[0]) == 4 && intval($version[1]) < 3)
{
	function array_chunk( &$array, $chunk_size )
	{
		$return_array = array();
		for ( $i = 0; $i < ceil(count($array) / $chunk_size); $i++ )
		{
			$return_array[] = array_slice($array,($i*$chunk_size),$chunk_size);
		}
		return $return_array;
	}
	function array_merge( $array1, $array2 )
	{
		while ( list($k,$v) = each ( $array2 ))
		{
			if( is_int($k) && isset($array1[$k]) )
			{
				$array1[] = $v;
			}
			else
			{
				$array1[$k] = $v;
			}
		}
		reset($array2);
		return $array1;
	}
}

class cash_notify
{
	function read(&$data)
	{
		$data[] = 'user_notify_cash';	// notify on a change in cash by means other than posting/spending
	}
}

// set our plugs
$config->set_plug_ins('mod_cash', array(
	'posting' => array(
		'layer' => array('includes/cash/class_cash_display', 'includes/cash/class_cash_parent', 'includes/cash/class_cash_' . POSTING),
		'object' => 'cash_posting',
	),
	'privmsg' => array(
		'layer' => array('includes/cash/class_cash_display', 'includes/cash/class_cash_parent', 'includes/cash/class_cash_privmsg'),
		'object' => 'cash_privmsg',
	),
	'modcp' => array(
		'layer' => 'includes/cash/class_cash_handler',
		'object' => 'cash_handler',
	),
	'viewtopic' => array(
		'layer' => 'includes/cash/class_cash_viewtopic',
		'object' => 'cash_viewtopic',
	),
	'class_forums' => array(
		'layer' => 'includes/cash/class_cash_plug_ins',
		'object' => 'cash_forums',
	),
	'class_posts' => array(
		'layer' => 'includes/cash/class_cash_display',
		'object' => 'cash_display',
	),
	'class_users' => array(
		'layer' => 'includes/cash/class_cash_handler',
		'object' => 'cash_handler',
	),
	'class_versions' => array(
		'object' => 'cash_version',
	),
	'class_advnot_parent' => array(
		'object' => 'cash_notify',
	),
));

?>